<?php
/**
 * PicBoard AJAX handler
 *
 * Each of the case's used here is a different AJAX request.
 *
 * PHP version 5
 *
 * LICENSE: <LICENCE-HERE>
 *
 * @author     Sebastian Skuse <scs@ecs.soton.ac.uk>
 * @copyright  2009-2010 University of Southampton
 * @license    http://<LICENSE-URL>  <LICENSE-NAME>
 * @version    CVS: $1:$
 */

/*
	$userObj is the passed user object, which will contain state, information about the current user, etc. (For more information see /system/classes/user.class.php)
	$language is the current language in use.
	additional arguments are passed through $args from the mod_rewrite.
*/

error_reporting(0);
require_once("system/core/main.php");
session_start();

$tmpUserObj = isset($_SESSION['userObject']) ? unserialize($_SESSION['userObject']) : '';

if(is_object($tmpUserObj) && ($tmpUserObj instanceof user)){
	$userObj = $tmpUserObj;
} else {
	// Create the state class
	$userObj = new user();
}


$language 	= isset($_POST['l']) ? $_POST['l'] : 'en';
$req		= isset($_GET['req']) ? $_GET['req'] : '';
$args		= isset($_GET['args']) ? $_GET['args'] : '';

$receivedArgs = array("language" => $language,
					 "extraArgs" => $args);

define('SYS_RUNLANG', $language);

switch($req){

	// Return a translation
	case "getTranslations":
		$_POST['terms'] = ( is_array($_POST['terms']) ) ? $_POST['terms'] : array($_POST['terms']);
		
		$lang = new language($_POST['terms'], $language);
		$lang->translate('table');
		returnJSONMessage("200", "success", "Translation successful", array("payload" => $lang->get() ) );
	break;
	
	case "getUploadDialog":
		if($userObj->getAccessLevel() > -1){

			if(isset($_POST['groupID']) == false){
				$imageLists = images::getUserLists( $userObj );	
			} else {
				
				$imageLists = images::getGroupLists($_POST['groupID']);
			}
			
			$data = new template("xhrfragment.uploadDialog");
			
			$out = "";
			
			foreach($imageLists as $list){
				$out .= sprintf("<option value=\"%s\">%s</option>", $list['isID'], $list['name']);
			}
			
			$data->replace('imageLocations', $out);
			
			$lang = new language($data->get(), $language);
			$lang->translate();
			
			echo $lang->get();
		}
	break;
	
	// Get a HTML fragment
	case "getFragment":
		$f = isset($_GET['f']) ? $_GET['f'] : '';
		$p = "system/templates/xhrfragment." . $f . ".html";
		if(file_exists($p)){
			// Get the data.
			$data = file_get_contents($p);
			// Perform any translations required on it.
			$lang = new language($data, $language);
			$lang->translate();
			
			// Send the translated data to the client.
			echo $lang->get();
		} else {
			$data = file_get_contents("system/templates/xhrfragment.404.html");
			// Perform any translations required on it.
			$lang = new language($data, $language);
			$lang->translate();
			
			// Send the translated data to the client.
			echo $lang->get();
		}
	break;
	
	case "getInitInfo":
		if($userObj->getAccessLevel() != -1){
			$messages = new messaging($userObj);
		
			echo json_encode(array(
				"institutions"=> $userObj->rtnInstitution(),
				"groups"=> $userObj->getManagedGroups(),
				"languages"=> $userObj->getAvailableLanguages(),
				"messages"=> $messages->getUnread()
			));
		} else {
			echo json_encode(array(
				"languages"=> $userObj->getAvailableLanguages()
			));		
		}
	break;
	
	// User is perfoming a search
	case "performSearch":
		
		if(isset($language)){
			// Defined in main.php
			$allowedExtensions = unserialize(SYS_API_ALLOWED_EXTENSIONS);
			if(in_array("svc" . $_POST['lib'], $allowedExtensions)){
				$apiExtension = "svc" . trim($_POST['lib']);
				
				$searchArgs = array("term" => $_POST['term'], "method" => $_POST['type']);
				
				// If we're requesting a page, add it to the arguments sent to the API
				if(isset($_POST['page'])) $searchArgs['page'] = $_POST['page'];
				
				$args = array_merge($receivedArgs, $searchArgs);
				
				// Find out the required arguments from the extension.
				eval("\$reqArguments = $apiExtension::getArguments();");
				
				if( count(array_intersect_key( $reqArguments, array_keys($args))) !== count($reqArguments)) {
					// Request has not provided all the arguments that are required for this method.
					returnJSONMessage("405", "failure", "Method has not received all required arguments.");
				} else {
					$service = new $apiExtension( $args );
					$service->search();
					
					$results = json_decode( $service->getResults(), true);
					$results['personalImages'] = images::searchUserImages($userObj, $searchArgs['term']);
					
					echo json_encode($results);
				}
				
				// Build up an array of arguments to pass to the API extension.
			} else {
				returnJSONMessage("418", "failure", "Extension is not safe and has been disabled.");
			}
		} else {
			returnJSONMessage("405", "failure", "Method requires language to be set.");
		}

	break;

	case "groupAction":
	
		if($_POST['action'] == 'leave'){
			if( group::canLeaveGroup($userObj, $_POST['gID']) ){
				$data = file_get_contents("system/templates/xhrfragment.leaveGroupConfirmation.html");
			} else {
				$data = file_get_contents("system/templates/xhrfragment.leaveGroupDisallowed.html");
	
			}
			// Perform any translations required on it.
			$lang = new language($data, $language);
			$lang->translate();
			
			// Send the translated data to the client.
			echo $lang->get();
		}
		
		if($_POST['action'] == 'confirmleave'){
			// The user is confirming that they want to leave the group. Check that they are allowed to.
			if( group::canLeaveGroup($userObj, $_POST['gID']) == false ){
				returnJSONMessage("6675", "failure", "You are not allowed to leave this group - you are the only admin.");
			} else {
				if( group::leaveGroup($userObj, $_POST['gID']) ){
					returnJSONMessage("200", "success", "You have successfully left this group.");
				} else {
					returnJSONMessage("500", "failure", "We were unable to remove you from this group at this time.");
				}
			}
		}
		
		if($_POST['action'] == 'join'){
			if($userObj->isInGroup($_POST['gID'], user::GROUP_ALL) == false){
				$res = group::canJoinGroup($userObj, $_POST['gID']);
				if($res['status'] == true){
					// The user is allowed to join this group.
					$res = group::joinGroup($userObj, $_POST['gID'], $res['message']);
					returnJSONMessage("200", "success", "Join Successful", array("payload" => $res));
				
				} else {
					// The user is not allowed to join the group
					returnJSONMessage("500", "failure", "You are not allowed to join this group.");
				}
			} else {
				// User is already in this group, or is validating
				returnJSONMessage("500", "failure", "You are not allowed to join this group as you are already in it, or waiting to be validated.");
			}
		}
	break;
	
	case "createGroup":
		// Get the data from the POST request
		$group['Name'] 			= $_POST['groupName'];
		$group['Description'] 	= $_POST['groupDescription'];
		$group['Visibility'] 	= $_POST['groupVisibility'];
		$group['Institution'] 	= isset($_POST['institution']) ? $_POST['institution'] : 1;
		$group['InviteOnly'] = ($_POST['groupVisibility'] == 'groupInvite') ? 1 : 0;
		$group['IsPrivate'] = ($_POST['groupVisibility'] == 'groupPrivate' || $_POST['groupVisibility'] == 'groupInvite') ? 1 : 0;
		
		if( group::canCreateGroup($userObj, $group) ){
			$result = group::createGroup($userObj, $group);
			
			if($result['status'] == "success"){
				// The group creation was successful. Send the result to the browser, which will direct them to the new group.
				returnJSONMessage("200", "success", "Group creation successful", array("groupID" => $result['groupID']) );
			} else {
				returnJSONMessage("500", "failure", "There was an error while creating this group. Please try again later.");
			}
		} else {
			returnJSONMessage("500", "failure", "You are not allowed to create a group with the information you have provided.");
		}
	
	break;
	
	case "updateGroup":
		if($userObj->getAccessLevel() > -1){
			try {
				if(group::updateGroup($userObj, (int)$_POST['gID'], array("name" => $_POST['name'], "description" => $_POST['description'])) == true){
					returnJSONMessage(200, "success", "Group updated successfully.");
				} else {
					returnJSONMessage(509, "failure", "Unable to update group.");
				}
			} catch(PicBoardException $e){
				returnJSONMessage(200, "failure", "Unable to update group:" . $e->getMessage());
			}
		}
	break;
	
	case "createBook":
		
		$book['name']			= $_POST['name'];
		$book['description']	= $_POST['description'];
		$book['visibility']		= $_POST['visibility'];
		$book['type']			= $_POST['type'];
		$book['group_gID']		= isset($_POST['group_gID']) ? $_POST['group_gID'] : "";
		
		// Can the user create the book?
		if( book::canCreateBook($userObj, $book) ){
			$result = book::createBook($userObj, $book);
			if($result['status'] == "failure"){
				returnJSONMessage("504", "failure", $result['reason']);
			} else {
				returnJSONMessage("200", "success", "Book Created", array("payload" => $result));
			}
		} else {
			returnJSONMessage("506", "failure", "A book with the same name as the one you just tried to create already exists.");
		}
    
	break;

	case "updateCommunity":
		if($userObj->getAccessLevel() > -1){
			
			if(isset($_POST['instID']) == false) returnJSONMessage(500, "failure", "Institution ID not specified");
			
			if(institution::isInInstitution($userObj, $_POST['instID'], institution::MEMBERSHIP_ADMIN)){
				$result = institution::update($userObj, $_POST['instID'], array("name" => $_POST['name'], "description" => $_POST['description']));
				
				if($result){
					returnJSONMessage(200, "success", "Community updated");
				} else {
					returnJSONMessage(507, "failure", "Unable to save update");
				}
			} else {
				returnJSONMessage(500, "failure", "Access Denied");
			}
			
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;
	
	
	case "addGroupInstitution":
		if($userObj->getAccessLevel() > -1){
			try {
				if(institution::addGroup($userObj, (int)$_POST['instID'], (int)$_POST['gID'])){
					returnJSONMessage(200, "success", "Group added");
				} else {
					returnJSONMessage(507, "failure", "Unable to update group");
				}
				
			} catch(Exception $e){
				returnJSONMessage(507, "failure", "Unable to update group");
			}
			
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;
	
	
	case "removeGroupInstitution":
		if($userObj->getAccessLevel() > -1){
			try {
				$destination = isset($_POST['destination']) ? (int)$_POST['destination'] : institution::GROUP_RELINQUISH;
			
				if(institution::removeGroup($userObj, (int)$_POST['instID'], (int)$_POST['gID'], $destination)){
					returnJSONMessage(200, "success", "Group removed");
				} else {
					returnJSONMessage(507, "failure", "Unable to update group");
				}
				
			} catch(Exception $e){
				returnJSONMessage(507, "failure", "Unable to update group");
			}
			
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}	
	break;
	
	case "updateChart":
		if($userObj->getAccessLevel() > -1){
			if(chart::chartExistsAndModifiable($userObj, array('chartID' => $_POST['chartID']))){
				chart::updateChartDetails($userObj, $_POST['chartID'], $_POST['name'], $_POST['description']);
				returnJSONMessage(200, "success", "Chart updated");
			} else {
				returnJSONMessage(500, "failure", "You do not have permissions to update this chart.");
			}
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;
	
	case "deleteChart":
		$chartID = isset($_POST['chartID']) ? (int) $_POST['chartID'] : 0;
		
		if($chartID != 0){
			if(chart::chartExistsAndModifiable($userObj, array('chartID' => $_POST['chartID'])) == false){
				returnJSONMessage("400", "failure", "You do not have permissions to delete this chart.");
				exit;
			}
			
			if(chart::deleteChart($userObj, $chartID)){
				returnJSONMessage("200", "success", "Chart Deleted");
			} else {
				returnJSONMessage("400", "failure", "Unable to delete chart");
			}
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;
	
	case "publishChart":
		$chartID = isset($_POST['chartID']) ? (int) $_POST['chartID'] : 0;
		
		if($chartID != 0){
			
			// Can we publish this asset?
			
			$asset = new asset($userObj);
			
			$asset->setResource(asset::CHART, asset::RESOURCE_EXISTING, $chartID);
			$asset->setLocation(asset::LOCATION_PUBLIC);
			
			if( $asset->canPublish() ){
			
				$cloneOperation = chart::duplicateChart($userObj, $chartID, "", chart::LOCATION_PUBLIC);
				if($cloneOperation['status'] == "success"){
					returnJSONMessage("200", "success", "Book Published", array("newID" => $cloneOperation['chartID']));
				} else {
					returnJSONMessage("509", "failure", "Unable to publish this book at this current time.");
				}
				
			} else {
				$e = $asset->getMessage();
				if($e == ""){
					$assetData = $asset->get();
					returnJSONMessage("602", "failure", "Disallowed: Charts that you wish to publish may only contain Mulberry Symbols.", array("restrictedcharts" => array_keys($assetData['restrictedAssets'])));
				} else {
					returnJSONMessage("602", "failure", $e);
				}
			}
			
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;
	
	case "donateChartCheck":
		$chartID = isset($_POST['chartID']) ? (int) $_POST['chartID'] : 0;
		
		if($chartID != 0){
		
			$asset = new asset($userObj);
			
			$asset->setResource(asset::CHART, asset::RESOURCE_EXISTING, $chartID);
			$asset->setLocation(asset::LOCATION_GROUP, (int) $_POST['groupID']);
			
			if( $asset->canDonate() ){
				returnJSONMessage("200", "success", "Chart is donatable");
			} else {
				$assetData = $asset->get();
				returnJSONMessage("207", "warning", "This chart contains non-mulberry images. If you donate this chart, these images will be removed in the group's copy. Do you wish to continue?", array("restrictedcharts" => $assetData['restrictedAssets']));
			}
			
		} else {
			returnJSONMessage("509", "failure", "chartID not set");
		}
	break;
	
	case "donateChart":
		$chartID = isset($_POST['chartID']) ? (int) $_POST['chartID'] : 0;
		
		if($chartID != 0){
		
			$donateOperation = chart::duplicateChart($userObj, $chartID, "", chart::LOCATION_GROUP, $_POST['groupID']);
			if($donateOperation){
				returnJSONMessage("200", "success", "Chart successfully donated");
			} else {
				returnJSONMessage("509", "failure", "Unable to clone chart");
			}
			
		} else {
			returnJSONMessage("509", "failure", "chartID not set");
		}
	break;
	
	case "retrieveChart":
		$chartID = isset($_POST['chartID']) ? (int) $_POST['chartID'] : 0;
		
		if($chartID != 0){
		
			$cloneID = chart::getGroupChartFromOriginalID($chartID, $_POST['groupID']);

			$asset = new asset($userObj);
			
			$asset->setResource(asset::CHART, asset::RESOURCE_EXISTING, $cloneID);
			$asset->setLocation(asset::LOCATION_GROUP, (int) $_POST['groupID']);
			
			if( $asset->canRetrieve() ){
				
				// Does the user have the original in their library?
				// If so, simply delete. Otherwise move from other library to ours.
				$original_owner = chart::chartOwnerID($chartID);
				
				// Does the book still exist?
				if(count($original_owner) > 0){
					// Yes, does it belong to us?
					if( $original_owner['user_uID'] == $userObj->getuID() ){
						// The object exists in the user's library. Simply delete from the remote library.
						
						$deleteOperation = chart::deleteChart($userObj, $cloneID);

						if($deleteOperation['status']){
							returnJSONMessage("200", "success", "Chart Retrieved");
						} else {
							returnJSONMessage("529", "failure", "Cannot retrieve chart at this current time", array("extraDetail" => $deleteOperation['reason'], "error" => $deleteOperation['error']));
						}
					} else {
						returnJSONMessage("549", "failure", "You are not the owner of this document's original.");
					}
				} else {
					// The asset no longer exists.
					// Move back to our library.
					if(chart::duplicateChart($userObj, $cloneID, "", chart::LOCATION_USER, $userObj->getuID()) == false){
						returnJSONMessage("509", "failure", "Cannot retrieve chart to your library at this current time");
						exit;
					}
					
					$deleteOperation = chart::deleteChart($userObj, $cloneID);
					
					if($deleteOperation['status']){
						returnJSONMessage("200", "success", "Chart Retrieved and copied to your library");
					} else {
						returnJSONMessage("509", "failure", "Cannot retrieve chart to your library at this current time", array("extraDetail" => "Could not delete from remote library", "returnedReason" => $deleteOperation['reason']));
					}
				}
				
				
			} else {
				returnJSONMessage("519", "failure", "Cannot retrieve book at this current time");
			}
			
		} else {
			returnJSONMessage("509", "failure", "chartID not set");
		}

	break;

	case "copyChart":
		$chartID = isset($_POST['chartID']) ? (int) $_POST['chartID'] : 0;

		if($chartID != 0){
		
			$location = ($_POST['newLocation'] == "private") ? asset::LOCATION_PRIVATE : asset::LOCATION_CURRENT;
			$id = ($_POST['newLocation'] == "private") ? $userObj->getuID() : 0;
			
			try {
			
				$asset = new asset($userObj);
				
				$asset->setResource(asset::CHART, asset::RESOURCE_NEW, $chartID);
				$asset->setLocation($location, $id);
				
				$asset->setNewDetails($_POST['newName'], "");
				
				if( $asset->canSave() ){
					// Get book details
					$chartDetails = chart::getChart($userObj, $chartID);
					
					
					if($location == asset::LOCATION_PRIVATE){
						$cloneOperation = chart::duplicateChart($userObj, $chartID, chart::LOCATION_USER, $userObj->getuID());
						
						if($cloneOperation){
							if(chart::updateChartDetails($userObj, $cloneOperation['chartID'], $_POST['newName'], $chartDetails['description']) == false) throw new PicBoardException("Unable to update chart details");
						} else {
							throw new PicBoardException("Unable to clone chart.");
						}
						
						returnJSONMessage("200", "success", "Chart Copied");
					}
					
					if($location == asset::LOCATION_CURRENT){
						$cloneOperation = chart::duplicatechart($userObj, $chartID, chart::LOCATION_GROUP, $chartDetails['group_gID']);
						
						if($cloneOperation){
							if(chart::updateChartDetails($userObj, $cloneOperation['chartID'], $_POST['newName'], $chartDetails['description']) == false) throw new PicBoardException("Unable to update chart details");
						} else {
							throw new PicBoardException("Unable to clone chart.");
						}
						
						returnJSONMessage("200", "success", "Chart Copied");
					}
				}
			
			} catch(Exception $e){
				returnJSONMessage("509", "failure", $e->getMessage());
			}
			
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;
	
	case "saveChart":
		
		// Is the user creating a new chart, or updating a current one?
		if( $_POST['chartSettings']['chartID'] == 0 ){
			// New chart
			
			// Is the user alowed to create this chart?
			$chartPermissions = chart::canCreateChart($userObj, $_POST['chartSettings']);

			if( $chartPermissions['status'] ){
				$creationStatus = chart::createChart($userObj, $_POST);

				if($creationStatus['status'] == "success"){
					// Success in creating the chart. Return the new ID to the user.
					returnJSONMessage("200", "success", "Chart Created", array("payload" => $creationStatus));
				} else {
					returnJSONMessage("400", "failure", $creationStatus['reason'], array("message" => $creationStatus['error_message']));
				}
			} else {
				returnJSONMessage("400", "failure", $chartPermissions['reason'], array("message" => $chartPermissions['reason']));
			}
		} else {
			// Does the chart exist? Does the user have permissions to edit it?
			$chartPermissions = chart::chartExistsAndModifiable($userObj, $_POST['chartSettings']);
			if( $chartPermissions['status'] == "success" ){

				// Create the chart
				$result = chart::updateChart($userObj, $_POST);
				if($result['status'] == "success"){
					returnJSONMessage("200", "success", "Chart Updated");
				} else {
					returnJSONMessage("400", "failure", $result['reason']);
				}
				
			} else {
				returnJSONMessage("400", "failure", $chartPermissions['reason']);
			}
		
		}
		
	break;

	case "deleteBook":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($bookID != 0){
			if(book::delete($userObj, $bookID)){
				returnJSONMessage("200", "success", "Book Deleted");
			} else {
				returnJSONMessage("400", "failure", "Unable to delete book");
			}
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;
	
	case "publishBook":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($bookID != 0){
			
			// Can we publish this asset?
			
			$asset = new asset($userObj);
			
			$asset->setResource(asset::BOOK, asset::RESOURCE_EXISTING, $bookID);
			$asset->setLocation(asset::LOCATION_PUBLIC);
			
			if( $asset->canPublish() ){
			
				$cloneOperation = book::cloneBook($userObj, $bookID, book::LOCATION_PUBLIC, 0);
				if($cloneOperation){
					returnJSONMessage("200", "success", "Book Published", array("newID" => $cloneOperation));
				} else {
					returnJSONMessage("509", "failure", "Unable to publish this book at this current time.");
				}
				
			} else {
				$assetData = $asset->get();
				returnJSONMessage("602", "failure", "Disallowed: Charts that you wish to publish may only contain Mulberry Symbols.", array("restrictedcharts" => array_keys($assetData['restrictedAssets'])));
			}
			
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;

	case "donateBookCheck":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($bookID != 0){
		
			$asset = new asset($userObj);
			
			$asset->setResource(asset::BOOK, asset::RESOURCE_EXISTING, $bookID);
			$asset->setLocation(asset::LOCATION_GROUP, (int) $_POST['groupID']);
			
			if( $asset->canDonate() ){
				returnJSONMessage("200", "success", "Book is donatable");
			} else {
				$assetData = $asset->get();
				returnJSONMessage("207", "warning", "This book contains charts with non-mulberry images. If you donate this book, these images will be removed in the group's copy. Do you wish to continue?", array("restrictedcharts" => $assetData['restrictedAssets']));
			}
			
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;
	
	case "donateBook":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($bookID != 0){
			
			$donateOperation = book::cloneBook($userObj, $bookID, book::LOCATION_GROUP, (int) $_POST['groupID']);
			if($donateOperation){
				returnJSONMessage("200", "success", "Book successfully donated");
			} else {
				returnJSONMessage("509", "failure", "Unable to clone book");
			}
			
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;
	
	case "retrieveBook":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($bookID != 0){
		
			$cloneID = book::getGroupBookFromOriginalID($bookID, $_POST['groupID']);

			$asset = new asset($userObj);
			
			$asset->setResource(asset::BOOK, asset::RESOURCE_EXISTING, $cloneID);
			$asset->setLocation(asset::LOCATION_GROUP, (int) $_POST['groupID']);
			
			if( $asset->canRetrieve() ){
				
				// Does the user have the original in their library?
				// If so, simply delete. Otherwise move from other library to ours.
				$original_owner = book::bookOwnerID($bookID);
				
				// Does the book still exist?
				if(count($original_owner) > 0){
					// Yes, does it belong to us?
					if( $original_owner['user_uID'] == $userObj->getuID() ){
						// The object exists in the user's library. Simply delete from the remote library.
						
						if(book::delete($userObj, $cloneID, true)){
							returnJSONMessage("200", "success", "Book Retrieved");
						} else {
							returnJSONMessage("509", "failure", "Cannot retrieve book at this current time");
						}
					} else {
						returnJSONMessage("509", "failure", "You are not the owner of this document's original.");
					}
				} else {
					// The asset no longer exists.
					// Move back to our library.
					if(book::cloneBook($userObj, $cloneID, book::LOCATION_USER, $userObj->getuID()) == false){
						returnJSONMessage("509", "failure", "Cannot retrieve book to your library at this current time");
						exit;
					}
					if(book::delete($userObj, $cloneID, true)){
						returnJSONMessage("200", "success", "Book Retrieved and copied to your library");
					} else {
						returnJSONMessage("509", "failure", "Cannot retrieve book to your library at this current time", array("extraDetail" => "Could not delete from remote library"));
					}
				}
				
				
			} else {
				returnJSONMessage("509", "failure", "Cannot retrieve book at this current time");
			}
			
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}

	break;

	case "copyBook":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;

		if($bookID != 0){
		
			$location = ($_POST['newLocation'] == "private") ? asset::LOCATION_PRIVATE : asset::LOCATION_CURRENT;
			$id = ($_POST['newLocation'] == "private") ? $userObj->getuID() : 0;
			
			try {
			
				$asset = new asset($userObj);
				
				$asset->setResource(asset::BOOK, asset::RESOURCE_NEW, $bookID);
				$asset->setLocation($location, $id);
				
				$asset->setNewDetails($_POST['newName'], "");
				
				if( $asset->canSave() ){
					// Get book details
					$bookDetails = book::getBook($userObj, $bookID);
					
					
					if($location == asset::LOCATION_PRIVATE){
						$cloneOperation = book::cloneBook($userObj, $bookID, book::LOCATION_USER, $userObj->getuID());
						
						if($cloneOperation){
							if(book::updateDetails($userObj, $cloneOperation, array(
								"name" => $_POST['newName'],
								"description" => $bookDetails['description']
							)) == false) throw new PicBoardException("Unable to update book details");
						} else {
							throw new PicBoardException("Unable to clone book.");
						}
						
						returnJSONMessage("200", "success", "Book Copied");
					}
					
					if($location == asset::LOCATION_CURRENT){
						$cloneOperation = book::cloneBook($userObj, $bookID, book::LOCATION_GROUP, $bookDetails['group_gID'], false);
						
						if($cloneOperation){
							if(book::updateDetails($userObj, $bookID, array(
								"name" => $_POST['newName'],
								"description" => $bookDetails['description']
							)) == false) throw new PicBoardException("Unable to update book details");
						} else {
							throw new PicBoardException("Unable to clone book.");
						}
						
						returnJSONMessage("200", "success", "Book Copied");
					}
				}
			
			} catch(Exception $e){
				returnJSONMessage("509", "failure", $e->getMessage());
			}
			
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;

	case "updateBook":
		// Is bookID set to anything? If not, set it to 0 otherwise we'll get a notice.
		$_POST['bookID'] = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($_POST['bookID'] != 0){
			// Does the user have permission to update this book?
			if(book::updateDetails($userObj, $_POST['bookID'], array("name" => $_POST['name'], "description" => $_POST['description']))){
				returnJSONMessage("200", "success", "Book Updated");	
			} else {
				returnJSONMessage("607", "failure", "Access Denied - you do not have access to this book.");
			}
		} else {
			returnJSONMessage("509", "failure", "bookID not set");
		}
	break;

	case "saveBook":
		
		// Is this a new book, or a current book?
		if( $_POST['bookID'] == 0 ){
			// New book
			
			$group_ID = (isset($_POST['group_gID']) && $_POST['group_gID'] != "0") ? $_POST['group_gID'] : "";
			
			$book = array("name" => $_POST['bookName'], "type" => ($group_ID == "") ? "personal" : "group",  "description" => $_POST['description'], "visibility" => $_POST['visibility'], "group_gID" => $group_ID);
			
			if( book::canCreateBook($userObj, $book) ){
				// Create the book
				$res = book::createBook($userObj, $book);
				if($res['status'] == "success"){
					// Duplicate any charts if this is in a group
					if($_POST['group_gID'] != "" && (int)$book['group_gID'] != 0){
						// User is saving this to a group. Duplicate charts.
						foreach($_POST['charts'] as $chart){
							$chartData = chart::getChart($userObj, $chart);
							$chartData['group_gID'] = $book['group_gID'];
							
							$sendData = array("chartSettings" => $chartData['data']['chart'], "cellSettings" => $chartData['data']['cells']);
							
							$sendData['chartSettings']['visibility'] = $sendData['chartSettings']['private'];
							$sendData['chartSettings']['title'] = $sendData['chartSettings']['name'];
							
							$i = 1;
							foreach($sendData['cellSettings'] as &$cell){
								$cell['imageID'] = $cell['image_imgID'];
								$cell['image'] = $cell['mulberryURL'];
								$cell['absolutePos'] = $i;
								$cell['colour'] = $cell['textColour'];
								$cell['bgcolour'] = $cell['bgColour'];
								$cell['PBCbold'] = $cell['textBold'];
								$cell['PBCitalic'] = $cell['textItalic'];
								$cell['PBCunderline'] = $cell['textUnderline'];
								$i++;
							}
							
							$newChart = chart::saveChartAs($userObj, $chart, $sendData );
							
							if($newChart['status'] == "success"){
								book::linkChartBook($userObj, $newChart['chartID'], $res['bookID']);
							} else {
								returnJSONMessage("506", "failure", $newChart['message']);
							}
							
							returnJSONMessage("200", "success", "Book Created", array("payload" => $result));
						}
					}
				} else {
					returnJSONMessage("400", "failure", $res['reason']);
				}
			
			} else {
				returnJSONMessage("506", "failure", "A book with the same name as the one you just tried to create already exists.");
			}
			
		} else {
			// Saving current book
			
			$book = array("bID" => $_POST['bookID'],
							"bookName" => $_POST['bookName'],
							"description" => $_POST['description'],
							"visibility" => $_POST['visibility'],
							"type" => $_POST['type'],
							"charts" => $_POST['charts']
			);
			
			$result = book::updateBook($userObj, $book);
			
			if($result == true){
				returnJSONMessage("200", "success", "Book Updated");
			} else {
				returnJSONMessage("400", "failure", "Unable to save book");
			}
			
			// Is the user allowed to save over this book (do they own it? Is it a group book? if so, are they an admin?)
		}
		
	break;
	
	case "getImportableCharts":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($userObj->getAccessLevel() > -1){
			$bookLocation = book::getBookLibrary($bookID, true);
			
			if($bookLocation['library'] == "My Books"){
				// Get a list of the charts that are in this book.
				$bookCharts = chart::getBookCharts($bookID, 500);
				
				// Get a list of available charts.
				$userCharts = chart::getUserCharts($userObj->getuID(), 500);

				// Return charts not in the diff.
				$charts = array_udiff($userCharts, $bookCharts, function($a, $b) {
					return ($a['chID'] - $b['chID']);
				});
				
				returnJSONMessage(200, "success", "Charts fetched", array("payload" => $charts, "chartPages" => book::getBookPositionCount($userObj, $bookID)));
				
			} else {
				// Get a list of the charts that are in this book.
				$bookCharts = chart::getBookCharts($bookID, 500);
				
				// Get a list of available charts.
				$userCharts = chart::getGroupCharts($bookLocation['gID'], 500);

				// Return charts not in the diff.
				$charts = array_udiff($userCharts, $bookCharts, function($a, $b) {
					return ($a['chID'] - $b['chID']);
				});
				
				returnJSONMessage(200, "success", "Charts fetched", array("payload" => $charts, "chartPages" => book::getBookPositionCount($userObj, $bookID)));
			}
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break; 
	
	case "addLinkChartBook":
		$bookID = isset($_POST['bookID']) ? (int) $_POST['bookID'] : 0;
		
		if($userObj->getAccessLevel() > -1){

			$position = (int) $_POST['atID'] + (int) $_POST['side'];
			if( book::linkChartBook($userObj, $_POST['chartID'], $_POST['bookID'], $position) ){
				returnJSONMessage(200, "success", "Chart Linked");
			} else {
				returnJSONMessage(607, "failure", "Unable to link chart to this book");
			}

		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;
	
	case "moveChartPositionBook":
		if($userObj->getAccessLevel() > -1){
			if($_POST['direction'] == "up") $direction = book::MOVE_UP;
			if($_POST['direction'] == "down") $direction = book::MOVE_DOWN;
			
			try {
				book::moveChartPosition($userObj, $_POST['bID'], $_POST['chID'], $direction);
				returnJSONMessage(200, "success", "Chart reordered");
				
			} catch(Exception $e){
				returnJSONMessage(607, "failure", "Unable to move chart position", array("details" => $e->getMessage() ));
			}
				
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;
	
	case "removeChartLink":
		if($userObj->getAccessLevel() > -1){
			try {
			
				book::removeLinkChartBook($userObj, $_POST['chartID'], $_POST['bookID']);
				
				returnJSONMessage(200, "success", "Link Removed");
				
			} catch(Exception $e){
				returnJSONMessage(705, "failure", "Unable to remove chart from book", array("details" => $e->getMessage() ));
			}
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;
	
	case "createAcct":
		$data = array("firstname" => $_POST['create_name'], "surname" => $_POST['create_surname'], "email" => $_POST['create_email'], "userName" => $_POST['create_username'], "password" => $_POST['create_password']);
		$res = users::createUser( $data );
		
		if($res['status'] == "success"){
			returnJSONMessage("200", "success", "AccountCreated");
		} else {
			switch($res['reason']){
			
				case "emailExists":
					$message = "The email address you have entered already exists. Please choose a different email.";
				break;
			
				case "userExists":
					$message = "The user account already exists. Please choose a different username.";
				break;
			
				default:
					$message = "An unknown error has occured.";
				break;
			}
			returnJSONMessage("400", "failure", $message);
		}
	break;

	case "verifyUsername":
		echo users::usernameExists($_POST['username']);
	break;
	
	case "addInstUsers":
		
		if(institution::addUsers($userObj, $_POST['id'], $_POST['data']) ){
			returnJSONMessage(200, "success", "Institution Users Added");
		} else {
			returnJSONMessage(409, "failure", "unabletoAddUsers");
		}
	
	break;


	case "getUserList":
	
		if($userObj->getAccessLevel() == 1){
			$page = (int)$_POST['userPagination'];
			$page--;
			$filters = array("email" => $_POST['filter_search'], "state" => $_POST['userState']);		
		 	$list = users::getUserList($userObj, $filters, $page);
		 	
		 	if(count($list) > 0){
		 		returnJSONMessage(200, "success", "userListGenerated", $list);
		 	}
		 }
	break;
	
	case "removeUsers":
		if($userObj->getAccessLevel() == 1 && isset($_POST['ids'])){
			$res = users::removeUsers($userObj, $_POST['ids']);
			if($res['status'] == 'success'){
				returnJSONMessage(200, "success", "usersDeleted");
			} else {
				returnJSONMessage(502, "failure", "Unable to delete users: " . $res['reason']);
			}
		}
	break;

	case "promoteUsers":
		if($userObj->getAccessLevel() == 1 && isset($_POST['ids'])){
			$result = users::promoteToAdmin( $userObj, $_POST['ids'] );
			
			if($result['status'] == true){
				returnJSONMessage(200, "success", "usersPromoted");
			} else {
				returnJSONMessage("400", "failure", "Unable to promote users");
			}
		} else {
			returnJSONMessage("400", "failure", "Insufficient permissions");
		}
	break;

	case "demoteUsers":
		if($userObj->getAccessLevel() == 1 && isset($_POST['ids'])){
			$res = users::demoteToUser($userObj, $_POST['ids']);
			
			if($res['status'] == true){
				returnJSONMessage(200, "success", "usersDemoted");
			} else {
				returnJSONMessage("400", "failure", $res['reason']);
			}
		}
	
	break;

	case "activateUsers":
		if( $userObj->getAccessLevel() == 1 && isset($_POST['ids']) ){
			$res = users::activateUsers( $userObj,$_POST['ids'] );
			
			if($res['status'] == true){
				returnJSONMessage(200, "success", "usersActivated");
			} else {
				returnJSONMessage("400", "failure", $res['reason']);
			}			
		} else {
			returnJSONMessage("400", "failure", "Insufficient permissions");
		}
	break;

	case "deactivateUsers":
		if( $userObj->getAccessLevel() == 1 && isset($_POST['ids']) ){
			$res = users::deactivateUsers( $userObj,$_POST['ids'] );
			
			if($res['status'] == true){
				returnJSONMessage(200, "success", "usersDeactivated");
			} else {
				returnJSONMessage("400", "failure", $res['reason']);
			}			
		} else {
			returnJSONMessage("400", "failure", "Insufficient permissions");
		}
	break;

	case "validateUsername":
		if($userObj->getAccessLevel() > -1){
			if(isset($_POST['email'])) {
				users::usernameExists($_POST['email'], true) ? returnJSONMessage(200, "success", "userExists") : returnJSONMessage(4018, "failure", "userDoesNotExist");
			}
			
			if(isset($_POST['username'])) {
				users::usernameExists($_POST['username']) ? returnJSONMessage(200, "success", "userExists") : returnJSONMessage(4018, "failure", "userDoesNotExist");
			}
		} else {
			returnJSONMessage(4018, "failure", "noUsername");
		}
	break;
	
	case "shareMedia":
		if($userObj->getAccessLevel() > -1 && isset($_POST['chartID']) && isset($_POST['list']) ){

			$res = users::shareMediaWithUserList( $userObj, $_POST['chartID'], $_POST['list'] );
			if($res['status'] == true) {
				returnJSONMessage(200, "success", "mediaShared");
			} else {
				returnJSONMessage("400", "failure", $res['reason'], array("exception" => $res['exception']));
			}
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;


	case "deleteChart":
		if(isset($_POST['id'])){
			$res = chart::deleteChart($userObj, (int)$_POST['id']);
			if($res['status']){
				returnJSONMessage(200, "success", "chartDeleted");
			} else {
				returnJSONMessage(500, "failure", "Unable To Delete", array("reason" => $res['reason']));
			}
		} else {
			returnJSONMessage(4018, "failure", "nochID");
		}
	break;
	
	
	case "duplicateChart":
		if($userObj->getAccessLevel() > -1 && isset($_POST['chartID'])){
			$res = chart::duplicateChart($userObj, $_POST['chartID'], $_POST['newName']);
			
			if($res['status'] == "success"){
				returnJSONMessage(200, "success", "chartDuplicated", array("chartID" => $res['chartID']));
			} else {
				returnJSONMessage(500, "failure", "Unable To Duplicate", array("reason" => $res['reason'], "error" => $res['error_message']));
			}
		} else {
			returnJSONMessage(4018, "failure", "nochID");
		}
	break;

	case "saveAsChart":
		// Get the settings for the chart that have been sent.
		$settings = $_POST['chartSettings'];
		if($userObj->getAccessLevel() > -1 && isset($settings['chartID'])){
			$chartPermissions = chart::canCreateChart($userObj, $settings);
			
			if($chartPermissions['status'] == 1){
				// User is allowed to create this chart. Proceed.
				$res = chart::saveChartAs($userObj, $settings['chartID'], $_POST);
				
				if($res['status'] == "success"){
					returnJSONMessage(200, "success", "chartCopySaved", array("chartID" => $res['chartID']));
				} else {
					returnJSONMessage(500, "failure", "Unable To Save", array("reason" => $res['reason'], "error" => $res['error_message']));
				}
			} else {
				// User is not allowed to create this.
				returnJSONMessage(500, "failure", "You cannot create a chart here because of " . $chartPermissions['reason']);
			}
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "resetPassword":
		if(isset($_POST['reset_email'])){
			// Check to see if the user exists.
			$user = users::getUser($_POST['reset_email']);
			if(count($user) > 0){
				// Disallow users to reset the root user.
				if((int)$user['uID'] == 1) {
					returnJSONMessage(509, "failure", "You cannot reset the root user.");
					exit;
				}
			
				$invite = new invite(new template('email.resetPassword'));
			
				$email = $invite->generateResetEmail($_POST['reset_email']);
				
				mailHandler::sendMessage($_POST['reset_email'], "PicBoard Invitation", $email);
				
				returnJSONMessage(200, "success", "resetEmailSent");
			} else {
				returnJSONMessage(4018, "failure", "Please enter a valid email address.");
			}
		} else {
			returnJSONMessage(4018, "failure", "Please supply a valid email address.");
		}
	break;


	case "resetPasswordConfirm":
		// Are the values we need set?
		if(isset($_POST['PBpasswordField']) && isset($_POST['i'])){
			// Check to see if the invite code exists.
			$val = invite::match_hash($_POST['i']);
			
			if($val['type'] == "reset"){
				// This is a valid password reset invitation code
				
				$dbCon = db::singleton();
				
				$sql = "UPDATE " . SYS_DB_DBNAME . ".user SET password='" . md5($_POST['PBpasswordField']) . "' WHERE emailAddress='" . $val['email'] . "'";
				
				$dbCon->single( $sql );
				
				invite::delete_invite($_POST['i']);
				
				returnJSONMessage(200, "success", "Password Changed");
			} else {
				returnJSONMessage(4018, "failure", "Invalid information provided.");
			}
		} else {
			returnJSONMessage(4018, "failure", "Invalid information provided.");
		}
	break;

	case "inviteUsersGroup":
		$groupID = $_POST['id'];
		if($userObj->getAccessLevel() > -1 && $userObj->isInGroup($groupID, user::GROUP_ADMINONLY)){
			foreach($_POST['data'] as $newUser){
				// Get user information.
				$user = users::getUser($newUser['email'], true);
				$admin = $newUser['admin'] == "yes" ? 1 : 0;
				group::joinGroupWithUserId($userObj, $user['uID'], $groupID, "Invite", $admin);
			
			}
			
			returnJSONMessage(200, "success", "Users invited");
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;
	
	case "acceptGroupInvitation":
		if($userObj->getAccessLevel() > -1 && $userObj->isInGroup($_POST['gID'], user::GROUP_ALL) && isset($_POST['msgID'])){
			group::acceptInvitation($userObj, $_POST['gID'], $_POST['msgID']);
			returnJSONMessage(200, "success", "Invite Accepted");
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;
	
	case "rejectGroupInvitation":
		if($userObj->getAccessLevel() > -1 && $userObj->isInGroup($_POST['gID'], user::GROUP_ALL) && isset($_POST['msgID'])){
			group::rejectInvitation($userObj, $_POST['gID'], $_POST['msgID']);
			returnJSONMessage(200, "success", "Invite Rejected");
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;
	
	
	case "deleteMessage":
		if($userObj->getAccessLevel() > -1 && isset($_POST['msgID'])){
			$messaging = new messaging($userObj);
			
			$messaging->deleteMessage($_POST['msgID']);
			
			returnJSONMessage(200, "success", "Message Deleted");
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "deleteShares":
		if($userObj->getAccessLevel() < 0) returnJSONMessage(4018, "failure", "Insufficient Permissions");
		
		$inbox = ($_POST['type'] == "inbox") ? true : false;
		
		// Has the client sent any information?
		if(count($_POST['ids']) > 0){
			foreach($_POST['ids'] as $k=> $message){
				$res = users::removeShare( $userObj, $message['ouID'], $message['chID'], $inbox );
				
				if($res['status'] == false){
					returnJSONMessage(506, "failure", "An error occurred while deleting messages.");
				}
			}
			
			returnJSONMessage(200, "success", "Messages Deleted");
		} else {
			returnJSONMessage(4018, "failure", "Please supply a list of messages to delete.");
		}
	break;

	case "deleteImage":
		if($userObj->getAccessLevel() > -1){
			if(images::deleteImage($userObj, $_POST['id'])){
				returnJSONMessage(200, "success", "Image Deleted");
			} else {
				returnJSONMessage(506, "failure", "Unable to delete image");
			}
		} else {
			returnJSONMessage(4033, "failure", "Unable to delete image: Your session has timed out");
		}
	break;

	case "updateImage":
		if($userObj->getAccessLevel() > -1){
			// Get image details
			$asset = new asset($userObj);
			
			$asset->setResource(asset::IMAGE, asset::RESOURCE_EXISTING, (int)$_POST['imgID']);
			$asset->setLocation();
			
			$asset->setNewDetails($_POST['name'], $_POST['description']);
			
			if( $asset->canSave() ){
				try {
					images::updateImageDetails($userObj, $_POST['imgID'], $_POST['name'], $_POST['description']);
					returnJSONMessage(200, "success", "Image updated");
				} catch(Exception $e){
					returnJSONMessage(500, "failure", $e->getMessage());
				}
			} else {
				returnJSONMessage(500, "failure", "Unable to update image");
			}
			
			
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "checkImageName":
		if($userObj->getAccessLevel() > -1){
			if(isset($_POST['name']) && isset($_POST['isID'])){
				// Check to see if it exists in the group library.
				if(images::nameExists($userObj, $_POST['name'], $_POST['isID'])){
					returnJSONMessage(500, "failure", "This name is already in use, please choose another.");
				} else {
					returnJSONMessage(200, "success", "Name available");
				}
			} else {
				returnJSONMessage(500, "failure", "Invalid arguments supplied.");
			}
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "getGroupAlbums":
		if($userObj->getAccessLevel() > -1){
			// User is logged in
			
			if($userObj->isInGroup($_POST['gID'], user::GROUP_ADMINONLY)){
				// User is an admin of this group. Get the albums.
				
				$albums = images::getGroupLists($_POST['gID']);
				returnJSONMessage(200, "success", "Albums fetched", array("albums" => $albums));
			} else {
				// User is not in this group.
				returnJSONMessage(500, "failure", "You do not have permissions to view the albums for this group.");
			}
			
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;


	case "donateImage":
		if($userObj->getAccessLevel() > -1){

			if($userObj->isInGroup($_POST['groupID'], user::GROUP_ADMINONLY)){
				if(images::cloneImage($userObj, $_POST['imageID'], images::LOCATION_GROUP, $_POST['albumID'])){
					returnJSONMessage(200, "success", "Image Donated");
				} else {
					returnJSONMessage(500, "failure", "Unable to donate image at this time.");
				}
			} else {
				returnJSONMessage(500, "failure", "You do not have permissions to donate to this group.");
			}
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;


	case "retrieveImage":
		if($userObj->getAccessLevel() > -1){
	
			// Get the ID for the clone.
			$groupImageClone = images::getClones($userObj, $_POST['imageID'], images::LOCATION_GROUP, $_POST['groupID']);
	
			$asset = new asset($userObj);
			
			$asset->setResource(asset::IMAGE, asset::RESOURCE_EXISTING, (int) $groupImageClone[0]['imgID']);
			$asset->setLocation(asset::LOCATION_PUBLIC);
			
			if( $asset->canRetrieve() ){
				if( images::retrieveFromGroup($userObj, $groupImageClone[0]['imgID'], $_POST['groupID'], $_POST['albumID']) ){
					returnJSONMessage(200, "success", "Image Retrieved");
				} else {
					returnJSONMessage(500, "failure", "Unable to retrieve from the group at this time.");
				}
			} else {
				returnJSONMessage(500, "failure", "You do not have permissions to retrieve from this group.");
			}
		
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;

	
	case "createImageSet":
		if($userObj->getAccessLevel() > -1){
			if($_POST['name'] == ""){
				returnJSONMessage(500, "failure", "No Name Supplied");
				exit;
			}
		
			$visibility = ($_POST['imageset_private'] == "visible") ? 0 : 1;
			
			try {
				if($_POST['saveInto'] == "personal"){
					$result = images::createImageSet($userObj, $_POST['name'], $_POST['description'], $visibility);
				} else {
					$result = images::createGroupImageSet($userObj, $_POST['name'], $_POST['description'], $visibility, $_POST['groupID']);
				}
				
				if( $result ){
					returnJSONMessage(200, "success", "Imageset Created");
				} else {
					returnJSONMessage(500, "failure", "Unable to create imageset");
				}
			
			} catch(Exception $e){
				returnJSONMessage(500, "failure", $e->getMessage());
			}
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "deleteAlbum":
		if($userObj->getAccessLevel() > -1){
			try {
				if(album::deleteAlbum($userObj, $_POST['id'])){
					returnJSONMessage(200, "success", "Album Deleted");
				} else {
					returnJSONMessage(500, "failure", "Unable to delete Album");
				}
			} catch(Exception $e){
				returnJSONMessage(500, "failure", $e->getMessage());
			}
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;

	case "updateAlbum":
		if($userObj->getAccessLevel() > -1){
			try {
				if( album::updateDetails($userObj, $_POST['isID'], $_POST['name'], $_POST['description']) ){
					returnJSONMessage(200, "success", "Album Updated");
				} else {
					returnJSONMessage(500, "failure", "Unable to update album, please try again later");
				}
			} catch(Exception $e){
				returnJSONMessage(500, "failure", $e->getMessage());
			}
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;

	case "search":
		// Is the user logged in?
		if($userObj->getAccessLevel() > -1){
			// Create a new search object
			$query = new search($userObj);
			
			// Set the location of the query
			$query->setLocation($_POST['areaFilter']);
			// Set the content type
			$query->setContent($_POST['typeFilter']);
			$query->terms($_POST['filter_search']);
			
			$query->setResultFormat(new template('fragment.listDisplayItem'));
			
			$result = $query->fetch();

			echo $result;

		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "searchChart":
	
		if($userObj->getAccessLevel() > -1){
			$query = new search($userObj);
			
			$query->setLocation($_POST['areaFilter']);
			
			$query->terms($_POST['search_box']);
			
			$result = $query->searchCharts();
			returnJSONMessage(200, "success", "ChartsRetrieved", array("uID" => $userObj->getuID(), "payload" => $result));
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	
	break;
	
	case "searchBooks":
		if($userObj->getAccessLevel() > -1){
			$query = new search($userObj);
			
			$query->setLocation($_POST['areaFilter']);
			
			$query->terms($_POST['search_box']);
			
			$result = $query->searchBooks();
			returnJSONMessage(200, "success", "BooksRetrieved", array("uID" => $userObj->getuID(), "payload" => $result));
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "searchImages":
		if($userObj->getAccessLevel() > -1){
			$query = new search($userObj);

			$query->setLocation($_POST['photoFilter']);
			
			$query->terms($_POST['photo_search']);
			
			$result = $query->searchImages();
			returnJSONMessage(200, "success", "ImagesRetrieved", array("uID" => $userObj->getuID(), "payload" => $result));
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "searchImagesets":
		if($userObj->getAccessLevel() > -1){
			$query = new search($userObj);

			$query->setLocation($_POST['albumFilter']);
			
			$query->terms($_POST['album_search']);
			
			$result = $query->searchImagesets();
			returnJSONMessage(200, "success", "ImagesRetrieved", array("uID" => $userObj->getuID(), "payload" => $result));
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "searchCommunities":
		if($userObj->getAccessLevel() > -1){
			$query = new search($userObj);
			
			$query->terms($_POST['search_box']);
			
			$result = $query->searchCommunities();
			returnJSONMessage(200, "success", "CommunitiesRetrieved", array("uID" => $userObj->getuID(), "payload" => $result));		
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "deleteGroupConfirmation":
		if($userObj->getAccessLevel() > -1 && $userObj->isInGroup($_POST['gID'], user::GROUP_ADMINONLY)){
			$assets = group::getAssociatedAssets($userObj, $_POST['gID']);
			returnJSONMessage(200, "success", "AssetsRetrieved", array("payload" => $assets));
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "removeGroup":
		if($userObj->getAccessLevel() > -1){
			if(group::deleteGroup($userObj, $_POST['id'])){
				returnJSONMessage(200, "success", "Group Deleted");
			} else {
				returnJSONMessage(500, "failure", "Unable to delete group");
			}
			
		}
	break;

	case "acceptGroupJoinRequest":
		if($userObj->getAccessLevel() > -1){
			if(group::acceptJoinRequest($userObj, (int)$_POST['gID'], (int)$_POST['uID'])){
				returnJSONMessage(200, "success", "User Accepted");
			} else {
				returnJSONMessage(500, "failure", "Unable to accept user");
			}
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}
	break;

	case "denyGroupJoinRequest":
		if($userObj->getAccessLevel() > -1){
			if(group::rejectJoinRequest($userObj, (int)$_POST['gID'], (int)$_POST['uID'])){
				returnJSONMessage(200, "success", "User Rejected");
			} else {
				returnJSONMessage(500, "failure", "Unable to reject user");
			}
		} else {
			returnJSONMessage(500, "failure", "Access Denied");
		}	
	break;

	case "removeInstitution":
		// Is the user logged in?
		if($userObj->getAccessLevel() > -1){
			// Does the user have access to remove this institution (i.e. are they an admin)?
			
			if(institution::isInInstitution($userObj, $_POST['instID'], institution::MEMBERSHIP_ADMIN)){
			
				if(institution::remove($userObj, (int)$_POST['instID'], institution::ORPHANS_RELINQUISH)){
					returnJSONMessage(200, "success", "Institution Deleted");
				} else {
					returnJSONMessage(700, "failure", "Database error: Cannot delete");
				}
			} else {
				returnJSONMessage(500, "failure", "AccessDenied");
			}
			
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;
	
	case "addInstitution":	
		if($userObj->getAccessLevel() > -1){
			
			$visibility = isset($_POST['inst_private']) ? $_POST['inst_private'] : "visible";
			$visibility = ($visibility == "visible") ? 0 : 1;
			
			if($_POST['instOwnership'] == "") {
				returnJSONMessage(500, "failure", "NoBaseGroup");
				exit;
			}
			
			
			$institution = new institution();
			
			$id = $institution->create($userObj, $_POST['institution_name'], $_POST['communityDescription'], $_POST['instOwnership'], $visibility);
			
			if($id != false){
				returnJSONMessage(200, "success", "Institution Created", array("instID" => $id));
			} else {
				returnJSONMessage(500, "failure", "AccessDenied");
			}
			
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "userListFeed":
		if($userObj->getAccessLevel() > -1){
		
			$data = images::generateFormattedUserLists($userObj);
		
			$lang = new language($data, $language);
			$lang->translate();
			
			// Send the translated data to the client.
			echo $lang->get();
			
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;
	
	case "userImageFeed":
		if($userObj->getAccessLevel() > -1){
			$data = images::generateFormattedUserListImages($userObj, $_POST['id']);
		
			$lang = new language($data, $language);
			$lang->translate();
			
			// Send the translated data to the client.
			echo $lang->get();		
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "getPrintingFormats":
		if($userObj->getAccessLevel() > -1){
			$data = printStyle::getFormats();
			returnJSONMessage(200, "success", "PrintingFormatList", array("formats" => $data));
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "getUserBooks":
		if($userObj->getAccessLevel() > -1){
			$data = $userObj->getBooks();
			returnJSONMessage(200, "success", "BookList", array("books" => $data));
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}	
	break;
	
	case "getGroupBooks":
		if($userObj->getAccessLevel() > -1){
			// Is the user able to see this group?
			$userGroups = $userObj->getSubscribedGroupIDs();
			
			if( in_array($_POST['gID'], $userGroups) ){
				$groupBooks = book::getGroupBooks($_POST['gID']);
				
				returnJSONMessage(200, "success", "BookList", array("books" => $groupBooks));
			} else {
				returnJSONMessage(500, "failure", "AccessDenied");
			}
			
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;

	case "validateLogin":
		if(isset($_POST['PBusernameField'], $_POST['PBpasswordField'])){	
			
			if( $userObj->auth($_POST['PBusernameField'], $_POST['PBpasswordField']) == true ){
				// Login Successful
				$_SESSION['userObject'] = serialize($userObj);
				returnJSONMessage(200, "success", "Authentication Successful");
			} else {
				// Login unsuccessful. Show an error to the user.
				returnJSONMessage(500, "failure", "The login details you have provided are incorrect or your account has not yet been activated.");
			}
		
		} else {
			returnJSONMessage(500, "failure", "Credentials not provided");
		}
	break;

	case "getFormatList":
		if($userObj->getAccessLevel() > -1){
			
			// Create an array for us to prepare the printFormatting information in.
			$output = array();
			
			// List of available formats
			$formats = unserialize(REGISTERED_OUTPUTS);
			foreach($formats as $printFormat){
				// Create the object and query it.
				$formatter = new $printFormat();
				
				// Don't use defaultformat.
				if($printFormat == "defaultFormat") continue;
				
				$output[ $printFormat ] = $formatter->get();
			}
			
			returnJSONMessage(200, "success", "Format List Retrieved", array("formats" => $output));
			
		} else {
			returnJSONMessage(500, "failure", "AccessDenied");
		}
	break;


	// No idea what the request we've been sent is for.
	default:
		returnJSONMessage("404", "failure", "Unknown request type.");
	break;

}


function returnJSONMessage($code, $status, $message, $properties = array()){
	$baseResponse = array("statusCode" => (int)$code, "status" => $status, "message" => $message);
	echo json_encode( array_merge($baseResponse, $properties) );
	exit;
}

?>